#ifndef THREADPOOL
#define THREADPOOL

#include <pthread.h>
#include <semaphore.h>
#include <list>

template<typename T>
class threadpool {
public:
    threadpool(int thread_number = 8, int max_requests = 10000);

    ~threadpool();

    bool append(T *request);

private:
    static void *worker(void *arg);  //c++中创建线程必须用静态函数
    void run();

private:
    int m_thread_number; //线程数量
    int m_max_requests; //最大请求数

    pthread_t *m_threads;  //线程号数组
    std::list<T *> m_workqueue; //工作队列

    pthread_mutex_t m_queuelocker; //工作队列的互斥锁
    sem_t m_queuestat;  //工作队列的信号量

    bool m_stop; //是否停止
};

//构造函数，创建时就构造线程
template<typename T>
threadpool<T>::threadpool(int thread_number, int max_requests) :
        m_thread_number(thread_number), m_max_requests(max_requests), m_stop(false), m_threads(NULL) {
    if ((thread_number <= 0) || (max_requests <= 0)) {
        throw std::exception();
    }

    m_threads = new pthread_t[m_thread_number];
    if (!m_threads) {
        throw std::exception();
    }

    if (sem_init(&m_queuestat, 0, 0) != 0 && pthread_mutex_init(&m_queuelocker, NULL) != 0) {
        throw std::exception();
    }

    for (int i = 0; i < thread_number; ++i) {
        printf("create the %dth thread\n", i);
        if (pthread_create(m_threads + i, NULL, worker, this) != 0) {
            delete[] m_threads;
            throw std::exception();
        }
        if (pthread_detach(m_threads[i])) //分离线程
        {
            delete[] m_threads;
            throw std::exception();
        }
    }
}

template<typename T>
void *threadpool<T>::worker(void *arg) {
    threadpool *pool = static_cast<threadpool *>(arg);
    pool->run();
    return pool;
}

template<typename T>
void threadpool<T>::run() {
    while (!m_stop) {
        sem_wait(&m_queuestat); //等待信号量
        pthread_mutex_lock(&m_queuelocker);
        if (m_workqueue.empty()) {
            pthread_mutex_unlock(&m_queuelocker);
            continue;
        }
        T *request = m_workqueue.front();
        m_workqueue.pop_front();
        pthread_mutex_unlock(&m_queuelocker);
        if (!request) {
            continue;
        }
        request->handleRequest(); //处理事务
    }
    pthread_mutex_unlock(&m_queuelocker);
    printf("thread exit\n");
    pthread_exit(NULL);
}

template<typename T>
bool threadpool<T>::append(T *request) {
    pthread_mutex_lock(&m_queuelocker);
    if (m_workqueue.size() > m_max_requests) {
        pthread_mutex_unlock(&m_queuelocker);
        return false;
    }
    m_workqueue.push_back(request);
    pthread_mutex_unlock(&m_queuelocker);
    sem_post(&m_queuestat); //增加信号量
    return true;
}


template<typename T>
threadpool<T>::~threadpool() {
    printf("Thread pool destroy !\n");
    m_stop = true;
    delete[] m_threads;

    pthread_mutex_destroy(&m_queuelocker);
    sem_destroy(&m_queuestat);
}


#endif